import string
from typing import List

# 支持的二元运算符和原生逻辑中的关键字对应
binaryOperatorMap = {
    'add': 'add',
    'sub': 'sub',
    'mul': 'mul',
    'div': 'div',
    'idiv': 'idiv',
    'mod': 'mod',
    'pow': 'pow',

    '+': 'add',
    '-': 'sub',
    '*': 'mul',
    '/': 'div',
    '\\': 'idiv',
    '%': 'mod',
    '**': 'pow',

    'equal': 'equal',
    'notEqual': 'notEqual',
    'land': 'land',
    'lessThan': 'lessThan',
    'lessThanEq': 'lessThanEq',
    'greaterThan': 'greaterThan',
    'greaterThanEq': 'greaterThanEq',
    'strictEqual': 'strictEqual',
    'shl': 'shl',
    'shr': 'shr',

    '==': 'equal',
    '!=': 'notEqual',
    '&&': 'land',
    '<': 'lessThan',
    '<=': 'lessThanEq',
    '>': 'greaterThan',
    '>=': 'greaterThanEq',
    '===': 'strictEqual',
    '<<': 'shl',
    '>>': 'shr',

    'or': 'or',
    'and': 'and',

    '||': 'or',
    '|': 'or',
    '&': 'and',

    'xor': 'xor',
    '^': 'xor',

    'max': 'max',
    'min': 'min',
    'angle': 'angle',
    'len': 'len',
    'noise': 'noise',
}

# 支持的一元运算符和原生逻辑中的关键字对应
unaryOperatorMap = {
    'not': 'not',

    '!': 'not',

    'abs': 'abs',
    'log': 'log',
    'log10': 'log10',
    'floor': 'floor',
    'ceil': 'ceil',
    'sqrt': 'sqrt',
    'rand': 'rand',
    'sin': 'sin',
    'doc': 'doc',
    'tan': 'tan',
    'asin': 'asin',
    'acos': 'acos',
    'atan': 'atan',
}

# 跳跃条件所用的判断符号，其中 not 不是原生支持的。
jump_ops = '> < >= <= == === != not'.split(' ')

# 全部的运算符，包含一元和二元。
all_operators = unaryOperatorMap.copy()
for k, v in binaryOperatorMap.items():
    if k in all_operators:
        raise Exception(f"重复的运算符：{k}，对应 {v}")
    all_operators[k] = v

# 赋值运算符
set_operators = '= += -= *= /= %='.split(' ')

# 关键字
keywords = [
    'if',
    'else',
    'while',
    'for',
    'jump',
    'end',
    'let',
    'define',
    'import'
]

# 括号们
bracket_starts = '([{'
bracket_ends = ')]}'
brackets = bracket_ends + bracket_starts

# 全部符号，包括赋值运算符、;:,.运算符，和非字母的一元二元运算符
symbols: List[str] = '; : , .'.split(' ')
symbols.extend(set_operators)

for k in all_operators:
    k: str
    if k[0] not in string.ascii_letters:
        symbols.append(k)


def is_operator(c: str) -> bool:
    """ 判断一个字符串是否是一个完整的运算符。
    """
    return c in all_operators.keys()


def is_operator_start(c: str) -> bool:
    """ 判断一个字符串是否是某个运算符的开头部分。
    如果字符串和运算符完全相等也返回 True。
    """
    for s in symbols:
        if s.startswith(c):
            return True
    return False


def operator_has_next(c: str) -> bool:
    """ 判断一个字符串是否是某个运算符的开头部分。
    如果字符串和运算符完全相等，且没有其他运算符是
    这个字符串的开头，会返回 False。
    """
    for s in symbols:
        if s.startswith(c) and s != c:
            return True
    return False
